#!/bin/bash

# Clean project
rm -f Makefile standard_def.mk src/src.mk includes/gpu.hh includes/hardware.hh

if [ "$1" = "clean" ] ; then
    exit;
fi


# Check nb core
nb=$(cat /proc/cpuinfo | grep processor | wc -l)

if [ "$nb" != "1" ] ; then
    echo "#ifndef _HARDWARE" > includes/hardware.hh
    echo "#define _HARDWARE" >> includes/hardware.hh
    echo "#define CORES $nb" >> includes/hardware.hh
    echo "#include \"mt_convolution.hh\"" >> includes/hardware.hh
    echo "namespace MThread{}" >> includes/hardware.hh
    echo "using namespace MThread;" >> includes/hardware.hh
    echo "#endif" >> includes/hardware.hh
else 
    echo "#ifndef _HARDWARE" > includes/hardware.hh
    echo "#define _HARDWARE" >> includes/hardware.hh
    echo "#define CORES 2" >> includes/hardware.hh
    echo "#include \"s_convolution.hh\"" >> includes/hardware.hh
    echo "namespace Simple{}" >> includes/hardware.hh
    echo "using namespace Simple;" >> includes/hardware.hh
    echo "#endif" >> includes/hardware.hh
fi

# Check if cuda is enable
if which nvcc &> /dev/null ;
then 
    gxxcuda=nvcc
    cudaflags="-O2"
    cd CONFIG && make > /dev/null && ./CONFIG && cd ..
    cp ./CONFIG/gpu.hh includes

    echo "#ifndef _HARDWARE" > includes/hardware.hh
    echo "#define _HARDWARE" >> includes/hardware.hh
    echo "#define CORES $nb" >> includes/hardware.hh
    echo "#include \"cu_convolution.hh\"" >> includes/hardware.hh
    echo "namespace CUDA{}" >> includes/hardware.hh
    echo "using namespace CUDA;" >> includes/hardware.hh
    echo "#endif" >> includes/hardware.hh
else
    rm -f includes/gpu.hh
    touch includes/gpu.hh
fi

# Define flags and standard compilator
gxxflags="-Werror -Wall -O2"
gxx=g++

rootname=$(basename "`pwd`")

# Writing standard directories
    cat <<EOF>> standard_def.mk
#### Common variables for Makefiles

## Directories
ROOT=\$(shell pwd)
DIR_BIN=bin
DIR_SRC=src
DIR_OBJ=obj
DIR_LIB=lib
DIR_HDR=includes
DIR_DOC=doc
EOF
if [ "$gxxcuda" = "nvcc" ] ; then
# Writing where to find cuda stuff
    cat <<EOF>> standard_def.mk
#### variables using NVidia Cuda
CUDA_INSTALL_PATH ?= /usr/local/cuda
INCLUDES  += -I. -I\$(CUDA_INSTALL_PATH)/include

EOF

fi
# Writing standard compilator
    cat <<EOF>> standard_def.mk

## Compilation
GXX=$gxx
EOF
# Writing cuda compilator if enable
if [ "$gxxcuda" = "nvcc" ] ; then
    cat <<EOF>> standard_def.mk
GXXCUDA=$gxxcuda
EOF
fi

# Writing standard flags
    cat <<EOF>> standard_def.mk

# Flags for linking
CFLAGS=-I \$(ROOT)/\$(DIR_HDR)
# Flags for objects
CFLAGS_OBJ=-I \$(ROOT)/\$(DIR_HDR)
# Flags for libraries objects
CFLAGS_DYNAMIC_LIBS_OBJ=-fPIC
# Flags for libraries linkins
CFLAGS_DYNAMIC_LIBS=-shared
# Flags for Compil
CXXFLAGS=$gxxflags
EOF

# Writing flags for cuda if enable
if [ "$gxxcuda" = "nvcc" ] ; then
    cat <<EOF>> standard_def.mk
CXXFLAGS+=\$(INCLUDES)
CUDAFLAGS=$cudaflags
EOF
fi

# Writing standard lib flags
    cat <<EOF>> standard_def.mk
# Flags for somethings
LIBFLAGS=-lIL -lILU
EOF

# Writing lib flags for cuda if enable
if [ "$gxxcuda" = "nvcc" ] ; then
    cat <<EOF>> standard_def.mk
LIBFLAGS+= -L\$(CUDA_INSTALL_PATH)/lib64 -lcudart
EOF

fi

    cat <<EOF>> Makefile
include ./standard_def.mk

EXEC=\$(ROOT)/\$(DIR_BIN)/$rootname

all::  createdirectories \$(EXEC)

createdirectories::
	@mkdir -p \$(DIR_OBJ) \$(DIR_LIB) \$(DIR_BIN) \$(DIR_DOC)

-include \$(ROOT)/\$(DIR_SRC)/src.mk


.PHONY: clean doc cleandoc raz

doc:    
	@echo "Generating documentation"
	@doxygen > /dev/null
	@(cd \$(DIR_DOC)/latex && make > /dev/null)
	@(mv \$(DIR_DOC)/latex/refman.pdf \$(DIR_DOC)/$rootname.pdf)

clean:
	@echo "Deleting *.o"
	@rm -rf \$(DIR_OBJ) \$(DIR_LIB)

cleandoc :
	@echo "Deleting documentation"
	@rm -rf \$(DIR_DOC)/latex \$(DIR_DOC)/html \$(DIR_DOC)/$rootname.pdf

raz:
	@echo "Cleaning all"
	@rm -rf \$(DIR_OBJ) \$(DIR_LIB) \$(DIR_BIN) \$(DIR_DOC)


EOF
	#chmod u+x Makefile;


	#chmod u+x standard_def.mk
	
	cat <<EOF>> src/src.mk
SRC=\$(wildcard \$(ROOT)/\$(DIR_SRC)/*.cpp)
OBJ=\$(SRC:\$(ROOT)/\$(DIR_SRC)/%.cpp=\$(ROOT)/\$(DIR_OBJ)/%.o)
EOF

if [ "$gxxcuda" = "nvcc" ] ; then
	cat <<EOF>> src/src.mk
SRCCUDA=\$(wildcard \$(ROOT)/\$(DIR_SRC)/*.cu)
OBJ+=\$(SRCCUDA:\$(ROOT)/\$(DIR_SRC)/%.cu=\$(ROOT)/\$(DIR_OBJ)/%.o)

EOF

fi
	cat <<EOF>> src/src.mk

# Compilation of the program

\$(EXEC):\$(OBJ) #\$(DYNAMIC_LIBS:%=\$(ROOT)/\$(DIR_LIB)/%.so)
	@echo "Linking ............. : \${EXEC}"
	@\$(GXX) -o \$@ \$^ \$(CFLAGS) \$(LIBFLAGS) \$(CXXFLAGS)

# Compilation from sources (.cpp) to objects (.o)
\$(ROOT)/\$(DIR_OBJ)/%.o: \$(ROOT)/\$(DIR_SRC)/%.cpp
	@echo "Compiling ........... : \$@"
	@\$(GXX) -o \$@ -c \$< \$(CFLAGS_OBJ) \$(CXXFLAGS) 
EOF
if [ "$gxxcuda" = "nvcc" ] ; then
	cat <<EOF>> src/src.mk

# Compilation from sources (.cu) to objects (.o)
\$(ROOT)/\$(DIR_OBJ)/%.o: \$(ROOT)/\$(DIR_SRC)/%.cu
	@echo "Compiling cu ........... : \$@"
	@\$(GXXCUDA) -o \$@ -c \$< \$(CFLAGS_OBJ) \$(CUDAFLAGS) 
EOF
fi
	#cp ~/scripts/Doxyfile $rootname/Doxyfile

	#chmod u+x src/src.mk;

